using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Standard.Licensing;
using Standard.Licensing.Security.Cryptography;
using Standard.Licensing.Validation;

namespace Catastrophe.Common.SoftLicensing
{
	public class LicenseManager
	{
		public string PrivateKey { get; set; }

		public string PublicKey { get; set; }

		public string Password { get; set; }

		public void GenerateKey(string password)
		{
			if (password == null)
			{
				throw new ArgumentNullException("password");
			}
			this.Password = password;
			KeyGenerator keyGenerator = new KeyGenerator(256);
			KeyPair keyPair = keyGenerator.GenerateKeyPair();
			this.PrivateKey = keyPair.ToEncryptedPrivateKeyString(password);
			this.PublicKey = keyPair.ToPublicKeyString();
		}

		public License CreateLicense(string licenseType, string customer, string email, DateTime startTime, int days, int maxUsers = 1, string requestNo = "", string pubKeyValue = "")
		{
			Dictionary<string, string> additionalAttributes = new Dictionary<string, string>
			{
				{ "SYTLKJ Product", "SYTLKJ License Manager " },
				{ "PubKey", pubKeyValue },
				{ "SerialNo", requestNo }
			};
			Dictionary<string, string> productFeatures = new Dictionary<string, string>
			{
				{ "Sales", "true" },
				{ "Billing", "true" }
			};
			Guid id = Guid.NewGuid();
			DateTime date = startTime.AddDays(days);
			return License.New().As(this.GetLicenseType(licenseType)).WithUniqueIdentifier(id)
				.WithMaximumUtilization(maxUsers)
				.WithAdditionalAttributes(additionalAttributes)
				.WithProductFeatures(productFeatures)
				.LicensedTo(customer, email)
				.ExpiresAt(date)
				.CreateAndSignWithPrivateKey(this.PrivateKey, this.Password);
		}

		private LicenseType GetLicenseType(string licenseTyp)
		{
			if (!(licenseTyp == "Trial"))
			{
				if (licenseTyp == "Standard")
				{
					return LicenseType.Standard;
				}
				throw new Exception("未知授权类型!");
			}
			return LicenseType.Trial;
		}

		private static bool LicenseException(License license)
		{
			return license.Type == LicenseType.Trial;
		}

		public Tuple<bool, string> ValidateLicense(License license, string publicKey)
		{
			IEnumerable<IValidationFailure> enumerable = license.Validate().ExpirationDate().When(LicenseException)
				.And()
				.Signature(publicKey)
				.AssertValidLicense();
			IValidationFailure[] source = (enumerable as IValidationFailure[]) ?? enumerable.ToArray();
			string text = ((!source.Any()) ? "License is Valid" : source.Aggregate(string.Empty, (string current, IValidationFailure validationFailure) => current + validationFailure.HowToResolve + ": \r\n" + validationFailure.Message + "\r\n"));
			return new Tuple<bool, string>(text == "License is Valid", text);
		}

		public License LoadLicense(string licensFileName = "license.lic")
		{
			if (!File.Exists(licensFileName))
			{
				throw new Exception("缺少授权文件!");
			}
			FileStream stream = File.OpenRead(licensFileName);
			return License.Load(stream);
		}
	}
}
